import {
  getInstanceValue,
  replaceObjToBlank
} from './utils/index.js'
class Watcher {
  /**
   * Watcher 类，dom收集器，当对应data值改变时触发dom更新
   * @param {*} data 当前组件对象
   * @param {*} node 当前dom节点
   * @param {*} attribute dom属性绑定
   * @param {*} template dom textContent文本值
   */
  constructor(data, node, attribute, template) {
    this.node = node;
    this.data = data;
    this.attribute = attribute;
    this.template = template;
  }
  /**
   * 非数组类 dom更新
   * @param {*} value 
   */
  update (value) {
    const attribute = this.attribute;
    const data = this.data;
    const template = this.template;
    const reg = /\{\{(.*?)\}\}/g;
    if (attribute === 'value') { // 属性值设置
      this.node[attribute] = replaceObjToBlank(value)
    } else if (
      attribute === 'innerText' ||
      attribute === 'innerHTML' ||
      attribute === 'textContent'
    ) { // 节点值设置
      const tmp = template.replace(reg, (matched, placeholder) => {
        const trimSpaces = placeholder.trim()// 去除空白字符
        return getInstanceValue(trimSpaces.split('.'), data)
      })
      this.node[attribute] = replaceObjToBlank(tmp)
    } else if (attribute === 'style') { // 样式设置
      this.node.style.cssText = value;
    } else if (attribute === 'display') { // :show 显示与隐藏设置
      this.node.style[attribute] = value ? template : 'none'
    } else {
      this.node.setAttribute(attribute, value);
    }
  }
  /**
   * 数组类 dom更新
   * @param {*} value 
   */
  arrayUpdate (value, type) {
    const attribute = this.attribute;
    const template = this.template;
    const reg = /\{\{(.*?)\}\}/g;
    // 暂时只对push做处理
    if (type === 'push') {
      const node = this.node.firstElementChild.cloneNode(true)
      const attr = node.attributes
      for (let i = 0; i < attr.length; i++) {
        const name = attr.item(i).name
        if (name.indexOf('key') !== -1) { // 获取到 xx-key 索引
          const id = name.split('-')[0]
          node.setAttribute(name, value[id] ? value[id] : value)
          node[attribute] = template.replace(reg, (matched, placeholder) => {
            const keys = placeholder.split('.')
            return value[keys[keys.length - 1]]
          })
          this.node.appendChild(node)
        }
      }
    }
  }
}

export default Watcher